#include "testmystream.h"
#include <QDebug>
#include <QPushButton>
#include "CTime"


void PrintData(void* data, int nType)
{
	if (data != nullptr)
	{
		switch (nType)
		{
		case _FIRST_DATA_TYPE_:
			qDebug() << "ID: " << static_cast<STFirstData*>(data)->nFirstID << "first info: " << static_cast<STFirstData*>(data)->firstInfo;
			break;
		case _SECOND_DATA_TYPE_:
			qDebug() << "ID: " << static_cast<STSecondData*>(data)->nSecondID << "second info: " << static_cast<STSecondData*>(data)->secondInfo;
			break;
		case _THIRD_DATA_TYPE_:
			qDebug() << "ID: " << static_cast<STThirdData*>(data)->nThirdID << "third info: " << static_cast<STThirdData*>(data)->thirdInfo;
			break;
		default:
			break;
		}
	}
}

Worker::Worker(QObject* parent)
{
	m_bStop = false;
	m_myStack.Init();
	m_myStack.PrintData(PrintData);
	m_myStream.Init(20 * 1024 * 1024);
}

Worker::~Worker()
{
	requestInterruption();
	wait();
	quit();
}

void Worker::SlotPushFirstStack()
{
/*
	qsrand(time(NULL));
	int ID = qrand() % 10 + 10;*/
	static int ID = 0;
	ID++;
	STFirstData data;
	data.nFirstID = ID;
	std::string strBuff;
	strBuff.clear();
	strBuff = std::string("the stack id is ") + std::to_string(data.nFirstID);
	memcpy(data.firstInfo, strBuff.c_str(), sizeof(data.firstInfo));
	m_myStack.PushData((char*)(&data), sizeof(data));
	m_myStack.PrintData(PrintData);
}

void Worker::SlotPushSecondStack()
{
/*
	qsrand(time(NULL));
	int ID = qrand() % 100 + 100;
*/
	static int ID = 100;
	ID++;
	STSecondData data;
	data.nSecondID = ID;
	std::string strBuff;
	strBuff.clear();
	strBuff = std::string("the stack id is ") + std::to_string(data.nSecondID);
	memcpy(data.secondInfo, strBuff.c_str(), sizeof(data.secondInfo));
	m_myStack.PushData((char*)(&data), sizeof(data));
	m_myStack.PrintData(PrintData);
}

void Worker::SlotPushThirdStack()
{
	static int ID = 10000;
	ID++;
	/*qsrand(time(NULL));
	int ID = qrand() % 1000 + 1000;*/
	STThirdData data;
	data.nThirdID = ID;
	std::string strBuff;
	strBuff.clear();
	strBuff = std::string("the stack id is ") + std::to_string(data.nThirdID);
	memcpy(data.thirdInfo, strBuff.c_str(), sizeof(data.thirdInfo));
	m_myStack.PushData((char*)(&data), sizeof(data));
	m_myStack.PrintData(PrintData);
}

void Worker::SlotPopStack()
{
	m_myStack.PopData();
	m_myStack.PrintData(PrintData);
}

void Worker::SlotClear()
{
	system("cls");
}

void  Worker::SlotLoopFirst()
{
	/*qsrand(time(NULL));
	int ID = qrand() % 10 + 10;
*/
	static int ID = 0;
	ID++;
	STFirstData data;
	data.nFirstID = ID;
	std::string strBuff;
	strBuff.clear();
	strBuff = std::string("the queue id is ") + std::to_string(data.nFirstID);
	memcpy(data.firstInfo, strBuff.c_str(), sizeof(data.firstInfo));
	m_myStream.Write((char*)&data, sizeof(STFirstData));
	qDebug() << "Write data ID: " << data.nFirstID << "info: " << data.firstInfo;
	fflush(NULL);
}

void Worker::SlotLoopSecond()
{
/*
	qsrand(time(NULL));
	int ID = qrand() % 100 + 100;*/
	static int ID = 100;
	ID++;
	STSecondData data;
	data.nSecondID = ID;
	std::string strBuff;
	strBuff.clear();
	strBuff = std::string("the queue id is ") + std::to_string(data.nSecondID);
	memcpy(data.secondInfo, strBuff.c_str(), sizeof(data.secondInfo));
	m_myStream.Write((char*)&data, sizeof(STSecondData));
	qDebug() << "Write data ID: " << data.nSecondID << "info: " << data.secondInfo;
	fflush(NULL);
}


void Worker::SlotLoopThird()
{
/*
	qsrand(time(NULL));
	int ID = qrand() % 1000 + 1000;*/
	static int ID = 10000;
	ID++;
	STThirdData data;
	data.nThirdID = ID;
	std::string strBuff;
	strBuff.clear();
	strBuff = std::string("the queue id is ") + std::to_string(data.nThirdID);
	memcpy(data.thirdInfo, strBuff.c_str(), sizeof(data.thirdInfo));
	m_myStream.Write((char*)&data, sizeof(STThirdData));
	qDebug() << "Write data ID: " << data.nThirdID << "info: " << data.thirdInfo;
	fflush(NULL);
}

void Worker::StartThread()
{
	m_myStream.ClearStreamData();
	m_bStop = false;
	start();
}

void Worker::StopThread()
{
	m_bStop = true;
}

void Worker::run()
{
	while (!isInterruptionRequested())
	{
		if (m_bStop)
			break;

		STHeadData data;
		if (m_myStream.IsCanReadBuf() && m_myStream.CalcSizeFromHeader(data))
		{
				switch (data.nType)
				{
				case _FIRST_DATA_TYPE_:
				{
					STFirstData data;
					m_myStream.Read((char*)&data, sizeof(STFirstData));
					qDebug() << "Read Data" << "ID: " << data.nFirstID << "info: " << data.firstInfo;
					fflush(NULL);
				}
					break;
				case _SECOND_DATA_TYPE_:
				{	
					STSecondData data;
					m_myStream.Read((char*)&data, sizeof(STSecondData));
					qDebug() << "Read Data" << "ID: " << data.nSecondID << "info: " << data.secondInfo;
					fflush(NULL);
				}
					break;
				case _THIRD_DATA_TYPE_:
				{
					STThirdData data;
					m_myStream.Read((char*)&data, sizeof(STThirdData));
					qDebug() << "Read Data" <<  "ID: " << data.nThirdID << "info: " << data.thirdInfo;
					fflush(NULL);
				}		
				}
		}
		msleep(1000);
	}
}

TestMyStream::TestMyStream(QWidget *parent)
	: QMainWindow(parent)
{
	ui.setupUi(this);
	connect(ui.btnPushFirst, SIGNAL(clicked()), &m_worker, SLOT(SlotPushFirstStack()));
	connect(ui.btnPushSecond, SIGNAL(clicked()), &m_worker, SLOT(SlotPushSecondStack()));
	connect(ui.btnPushThird, SIGNAL(clicked()), &m_worker, SLOT(SlotPushThirdStack()));
	connect(ui.btnLoopFirst, SIGNAL(clicked()), &m_worker, SLOT(SlotLoopFirst()));
	connect(ui.btnLoopSecond, SIGNAL(clicked()), &m_worker, SLOT(SlotLoopSecond()));
	connect(ui.btnLoopThird, SIGNAL(clicked()), &m_worker, SLOT(SlotLoopThird()));
	connect(ui.btnPop, SIGNAL(clicked()), &m_worker, SLOT(SlotPopStack()));
	connect(ui.btnClear, SIGNAL(clicked()), &m_worker, SLOT(SlotClear()));
	m_worker.StartThread();
}

TestMyStream::~TestMyStream()
{

}

